// Copyright©,2020-2025
// Author: caocheng
// Version: 1.0.0
// Date: 2021/3/17 13:30
// Description：
package SummerStarter

import (
	"fmt"
	"net"
	"reflect"
	"runtime"

	"gitee.com/chrischo/go-summer/summer/summer-boot"
	"gitee.com/chrischo/go-summer/summer/summer-logger"
	"gitee.com/chrischo/go-summer/summer/summer-utils"
	"google.golang.org/grpc"
)

// EndpointConfig gRPC 服务端点配置 例 grpc.address:=127.0.0.1:9090 gRPC 服务器地址
type EndpointConfig struct {
	Address string
}

// Starter gRPC 服务器启动器
type RpcServerStarter struct {
	server *grpc.Server
}

// NewStarter Starter 的构造函数
func NewRpcServerStarter() *RpcServerStarter {
	return &RpcServerStarter{
		server: grpc.NewServer(),
	}
}

func (starter *RpcServerStarter) OnStartApplication(ctx SummerBoot.ApplicationContext) {

	srvMap := make(map[string]reflect.Value)

	v := reflect.ValueOf(starter.server)
	for fn, server := range SummerBoot.GRpcServerMap {
		if server.CheckCondition(ctx) {
			srv := reflect.ValueOf(server.Server())
			fn.Call([]reflect.Value{v, srv}) // 调用 gRPC 的服务注册函数
			srvMap[server.ServiceName()] = srv
		}
	}

	for service, info := range starter.server.GetServiceInfo() {
		srv := srvMap[service]
		for _, method := range info.Methods {
			m, _ := srv.Type().MethodByName(method.Name)
			fnPtr := m.Func.Pointer()
			fnInfo := runtime.FuncForPC(fnPtr)
			file, line := fnInfo.FileLine(fnPtr)
			SummerLogger.Infof("/%s/%s %s:%d ", service, method.Name, file, line)
		}
	}

	addr := fmt.Sprintf(":%d", ctx.GetStringProperty("grpc.server.port"))
	lis, err := net.Listen("tcp", addr)
	SummerUtils.Panic(err).When(err != nil)

	ctx.SafeGoroutine(func() {
		if err = starter.server.Serve(lis); err != nil {
			SummerLogger.Error(err)
		}
	})
}

func (starter *RpcServerStarter) OnStopApplication(ctx SummerBoot.ApplicationContext) {
	starter.server.GracefulStop()
}

// NewClientConn 根据配置创建 grpc.ClientConn 对象
func NewClientConn(address string) (*grpc.ClientConn, error) {
	return grpc.Dial(address, grpc.WithInsecure())
}
